package com.data.mining.project;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class HitCalculator
{
	private static final double EPSILON 	= 0.00001;

	
	private static class Vertex
	{
		public List< String> inlinks  = new ArrayList<String>( );
		public List< String> outlinks = new ArrayList<String>( );
		public double auth = 0;
		public double hub  = 0;
		public double old_auth = 1;
		public double old_hub = 1;
	}
	/**
	 * @param args
	 */
	public static void main( String[ ] args)
	{
		double DELTA	= 1;
		double oldMax   = 0;
		int    iterationNum = 0;
		Map< String, Vertex> graph = new HashMap< String, Vertex>( );
		
		readGraphFromFile( args[0], graph);
		while ( DELTA > EPSILON)
		{
			System.out.println( "Iteration: #" + (++iterationNum) );
			double max_hub = 0;
			double max_auth = 0;
			for( Integer i = 0; i < graph.size( ); ++i)
			{
				System.out.println( "Vertex: #" + i);
				for ( final String link : graph.get( i.toString( )).inlinks)
				{
					graph.get( i.toString( )).auth += graph.get( link).old_hub;
				}
				System.out.println( "Unnormalized authority: " + graph.get( i.toString( )).auth);
				max_auth = Math.max( max_auth, graph.get( i.toString( )).auth);
				for ( final String link : graph.get( i.toString( )).outlinks)
				{
					graph.get( i.toString( )).hub += graph.get( link).old_auth;
				}
				System.out.println( "Unnormalized hub: " + graph.get( i.toString( )).hub);
				max_hub = Math.max( max_hub, graph.get( i.toString( )).hub);
			}
			if ( oldMax != max_auth)
			{
				DELTA = Math.abs( oldMax - max_auth);
				oldMax = max_auth;
			}
			for ( Integer i = 0; i < graph.size( ); ++i)
			{
				graph.get( i.toString( )).old_auth = graph.get( i.toString( )).auth/max_auth;
				graph.get( i.toString( )).auth = 0;
				graph.get( i.toString( )).old_hub = graph.get( i.toString( )).hub/max_hub;
				graph.get( i.toString( )).hub = 0;
			}
			System.out.println( );
		}
		for ( Integer i = 0; i < graph.size( ); ++i)
		{
			System.out.println( "Vertex: #" + i.toString( ) + 
								" normalized authority value: " + graph.get( i.toString( )).old_auth +
								" nprmalized hub value:" + graph.get( i.toString( )).old_hub);
		}
	}
	private static void readGraphFromFile( String fileName, Map< String, Vertex> graph)
	{
		try
		{
			BufferedReader in = new BufferedReader( new FileReader(	fileName));
			String str;
			while ( ( str = in.readLine( )) != null)
			{
				String[ ] verticies = str.split( ">");
				if ( !graph.containsKey( verticies[0]))
					graph.put( verticies[0], new Vertex( ));
				if ( !graph.containsKey( verticies[1]))
					graph.put( verticies[1], new Vertex( ));
				graph.get( verticies[0]).outlinks.add( verticies[1]);
				graph.get( verticies[1]).inlinks.add( verticies[0]);
			}
			in.close( );
		} catch ( IOException e)
		{
			
		}
	}
}
